import { CMEVENTS } from '@amcax/base';
import { Picker3D, PickerMgr, Renderer3D, RendererMgr } from '@amcax/renderer';
import { getEventDispater } from './dispatcher';
import { docMgr } from '../../manager/DocumentManager';
import { wsApi } from '../../server/wsApi';
import { ctx2, dataManager, userEvents } from '../../module';

export interface CoreEvent {
  event: string;
  data: any;
}
interface CoreResEvent {
  added?: string[];
  modified?: string[];
  removed?: string[];
  shapechanged?: string[];
  placementchanged?: string[];
  materialchanged?: string[];
  visibilitychanged?: string[];
  propertychanged?: string[];
}

export function handleCoreEvent(edata: CoreEvent) {
  getEventDispater().dispatch(edata.event, edata.data);
}

const coreEventActive = getEventDispater().group('shapechangepending');

coreEventActive.handle('', async (event: CoreResEvent) => {
  const Render = RendererMgr.getRender<Renderer3D>('3d');
  const Picker = PickerMgr.getPicker<Picker3D>('3d');
  // 先更新全部
  // await ctx2.updateDocumentObjects()
  const added = event.added || [];
  const removed = event.removed || [];
  const shapeChanged = event.shapechanged || [];
  const placementChanged = event.placementchanged || [];
  const propertychange = event.propertychanged || [];
  const visibilitychanged = event.visibilitychanged || [];
  if (added.length > 0) {
    let firstTimeAdd = false;
    // await ctx2.updateDocumentObjects(added)
    docMgr.updateDocumentObjects(added);
    const modelDatas = await wsApi.getVisualData(added);
    if (modelDatas && (modelDatas as any).length > 0) {
      console.log('added  addedadded', added);
      if (ctx2.cadScene.edgeGroup.children.length === 0) {
        firstTimeAdd = true;
      }
      await Render.saveShapeDatas(modelDatas);
      await Render.drawNewModels(added);
      // add完成
      // ctx2.emit(EVENTS.MODEL_ADDED, added)
      userEvents.emit(CMEVENTS.MODEL_ADDED, added);

      added.forEach((dxid) => {
        const obj = dataManager.getObjectInfoByDxid(dxid);
        Render.setModelVisible(dxid, obj?.visibility);
      });

      ctx2.viewer.requestRender();
      ctx2.viewer.sceneSetup.updatePixelBuffer();
      ctx2.viewer.sceneSetup.fit2DView();
    }
  }
  if (shapeChanged.length > 0) {
    console.log('shapeChanged', shapeChanged);
    // await ctx2.updateDocumentObjects(shapeChanged);
    docMgr.updateDocumentObjects(shapeChanged);
    const modelDatas = await wsApi.getVisualData(shapeChanged);
    if (modelDatas && (modelDatas as any).length > 0) {
      await Render.saveShapeDatas(modelDatas);
      await Render.drawNewModels(shapeChanged);
    }
    // ctx2.emit(EVENTS.MODEL_SHAPE_CHANGED, shapeChanged);
    userEvents.emit(CMEVENTS.MODEL_SHAPE_CHANGED, shapeChanged);
    shapeChanged.forEach((dxid) => {
      const obj = dataManager.getObjectInfoByDxid(dxid);
      Render.setModelVisible(dxid, obj?.visibility);
    });
  }
  if (placementChanged.length > 0) {
    console.log('placementChanged', placementChanged);
    // await ctx2.updateDocumentObjects(placementChanged);
    docMgr.updateDocumentObjects(placementChanged);
    await Render.drawNewModels(placementChanged);
    Picker.clearPickedObjects();
    // ctx2.emit(EVENTS.MODEL_PLACEMENT_CHANGED, placementChanged);
    userEvents.emit(CMEVENTS.MODEL_PLACEMENT_CHANGED, placementChanged);
  }

  if (propertychange.length > 0) {
    console.log('propertychange', propertychange);
    // await ctx2.updateDocumentObjects(propertychange);
    docMgr.updateDocumentObjects(propertychange);
    ctx2.viewer.requestRender();
  }

  if (removed.length > 0) {
    console.log('removed', removed);
    Picker.deleteModels(removed);
    // await ctx2.updateDocumentObjects(removed);
    docMgr.updateDocumentObjects(removed);
    // remove完成
    // ctx2.emit(EVENTS.MODEL_REMOVED, removed)
    userEvents.emit(CMEVENTS.MODEL_REMOVED, removed);
  }
  if (visibilitychanged.length > 0) {
    console.log('visibilitychanged', visibilitychanged);
    // await ctx2.updateDocumentObjects(visibilitychanged)
    docMgr.updateDocumentObjects(visibilitychanged);
    for (let i = 0; i < visibilitychanged.length; i++) {
      const dxid = visibilitychanged[i];
      const obj = dataManager.getObjectInfoByDxid(dxid);
      const shape = obj.shape;
      const shapeData = dataManager.getShapeData(shape);
      if (!shapeData) {
        const modelDatas = await wsApi.getVisualData([dxid]);
        if (modelDatas && (modelDatas as any).length > 0) {
          await Render.saveShapeDatas(modelDatas);
          await Render.drawNewModels([dxid]);
        }
      } else {
        const visibility = obj.visibility;
        // Picker.setModelVisible(dxid, visibility)
        Render.setModelVisible(dxid, visibility);
      }
    }
    ctx2.viewer.requestRender();
    ctx2.viewer.sceneSetup.updatePixelBuffer();
  }
});

const groupSimulation = getEventDispater().group('simulationchangepending');

groupSimulation.useHook(async () => {
  docMgr.updateDocumentObjects();
});
